<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Services\AliSmsService;
use Illuminate\Http\Request;
use App\Models\SmsLog;
use Mrgoon\AliSms\AliSms;
use AlibabaCloud\SDK\Sts\V20150401\Sts;
use \Exception;
use AlibabaCloud\Tea\Exception\TeaError;
use AlibabaCloud\Tea\Utils\Utils;
use Darabonba\OpenApi\Models\Config;
use AlibabaCloud\SDK\Sts\V20150401\Models\AssumeRoleRequest;
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;

class AliSmsController extends Controller
{
    protected $sms_template_id = 'SMS_205129306'; // 公用验证码

    public function securityToken()
    {
        $access_id = \config('filesystems.disks.oss.sts_access_id');
        $access_secret = \config('filesystems.disks.oss.sts_access_secret');
        $endpoint = \config('filesystems.disks.oss.sts_endpoint');
        $sts_role_arn = \config('filesystems.disks.oss.sts_role_arn');
        $sts_role_session_name = \config('filesystems.disks.oss.sts_role_session_name');

        $config = new Config([
            // 必填，您的 AccessKey ID
            "accessKeyId" => $access_id,
            // 必填，您的 AccessKey Secret
            "accessKeySecret" => $access_secret
        ]);

        $config->endpoint = $endpoint;

        $client = new Sts($config);
        $assumeRoleRequest = new AssumeRoleRequest([
            "roleArn" => $sts_role_arn,
            "roleSessionName" => $sts_role_session_name
        ]);
        $runtime = new RuntimeOptions([]);
        try {
            $res = $client->assumeRoleWithOptions($assumeRoleRequest, $runtime);

            return $this->success($res->body->toMap());

        } catch (Exception $error) {
            if (!($error instanceof TeaError)) {
                $error = new TeaError([], $error->getMessage(), $error->getCode(), $error);
            }
            $message = Utils::assertAsString($error->message);

            return $this->failure($message);
        }
    }

    public function smsCode(Request $request)
    {
        $mobile = $request->get('mobile');
        $source = $request->get('source');
        if (!$mobile) {
            return $this->failure('手机号不能为空');
        }
        if (!AliSmsService::is_mobile($mobile)) {
            return $this->failure('手机号不正确');
        }

        $this->checkRate($mobile);
        $code = mt_rand(1000, 9999);
        $sms_log_obj = new SmsLog();
        $sms_log_obj->type = 0;//类型(0:短信验证码,1:语音验证码,2:短信消息通知)
        $sms_log_obj->mobile = $mobile;
        $sms_log_obj->code = $code;
        $sms_log_obj->checked = 0;//是否验证(0:未验证,1:已验证)
        $sms_log_obj->status = 0;//状态(0:未发送,1:已发送,2:发送失败)
        $sms_log_obj->ip = $request->getClientIp();
        $sms_log_obj->created = time();
        if ($sms_log_obj->save()) {

            try {
                $ali_sms = new AliSms();
                $response = $ali_sms->sendSms($mobile, $this->sms_template_id, ['code' => $code]);

                if ($response->Code == 'OK' && $response->Message == 'OK') {
                    $sms_log_obj->status = 1;
                    $sms_log_obj->save();
                    return $this->success($response->Message);
                } else {
                    return $this->failure('请求频繁');
                }
            } catch (\Exception $e) {
                $sms_log_obj->status = 2;
                $sms_log_obj->reason = $e->getMessage();
                $sms_log_obj->save();
                return $this->failure($e->getMessage());
            }
        } else {
            return $this->failure('验证码保存时出错');
        }
    }

    /**
     * 检测短信频率
     * @param $mobile
     * @return bool
     */
    protected function checkRate($mobile)
    {
        $sms_log = SmsLog::where('mobile', $mobile)->where('status', 1)->orderBy('created', 'desc')->first();
        $now = time();
        if ($sms_log) {
            if (($now - strtotime($sms_log->created)) < 60) {
                return $this->failure('短信发送太频繁,请稍后再试');
            }
        }
        return true;
    }

    public function isValid(Request $request)
    {
        $is_valid = AliSmsService::isValid($request->query('sms_code'), $request->query('mobile'));
        return $this->success(['is_valid' => $is_valid]);
    }
}
